using Microsoft.Expression.Drawing.Core;
using System;
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Expression.Media
{
	public abstract class GeometrySource<TParameters> : IGeometrySource where TParameters : IGeometrySourceParameters
	{
		private bool geometryInvalidated;
		protected Geometry cachedGeometry;
		public Geometry Geometry
		{
			get;
			private set;
		}
		public Rect LogicalBounds
		{
			get;
			private set;
		}
		public Rect LayoutBounds
		{
			get;
			private set;
		}
		public bool InvalidateGeometry(InvalidateGeometryReasons reasons)
		{
			if ((reasons & InvalidateGeometryReasons.TemplateChanged) != (InvalidateGeometryReasons)0)
			{
				this.cachedGeometry = null;
			}
			if (!this.geometryInvalidated)
			{
				this.geometryInvalidated = true;
				return true;
			}
			return false;
		}
		public bool UpdateGeometry(IGeometrySourceParameters parameters, Rect layoutBounds)
		{
			bool flag = false;
			if (parameters is TParameters)
			{
				Rect rect = this.ComputeLogicalBounds(layoutBounds, parameters);
				flag |= (this.LayoutBounds != layoutBounds || this.LogicalBounds != rect);
				if (this.geometryInvalidated || flag)
				{
					this.LayoutBounds = layoutBounds;
					this.LogicalBounds = rect;
					bool expr_5A = flag |= this.UpdateCachedGeometry((TParameters)((object)parameters));
					bool force = flag;
					flag = (expr_5A | this.ApplyGeometryEffect(parameters, force));
				}
			}
			this.geometryInvalidated = false;
			return flag;
		}
		protected abstract bool UpdateCachedGeometry(TParameters parameters);
		protected virtual Rect ComputeLogicalBounds(Rect layoutBounds, IGeometrySourceParameters parameters)
		{
			return GeometryHelper.Inflate(layoutBounds, -parameters.GetHalfStrokeThickness());
		}
		private bool ApplyGeometryEffect(IGeometrySourceParameters parameters, bool force)
		{
			bool result = false;
			Geometry outputGeometry = this.cachedGeometry;
			GeometryEffect geometryEffect = parameters.GetGeometryEffect();
			if (geometryEffect != null)
			{
				if (force)
				{
					result = true;
					geometryEffect.InvalidateGeometry(InvalidateGeometryReasons.ParentInvalidated);
				}
				if (geometryEffect.ProcessGeometry(this.cachedGeometry))
				{
					result = true;
					outputGeometry = geometryEffect.OutputGeometry;
				}
			}
			if (this.Geometry != outputGeometry)
			{
				result = true;
				this.Geometry = outputGeometry;
			}
			return result;
		}
	}
}
